package com.example.nio.three;

import com.example.nio.two.ReadSelectorThread2;
import com.example.nio.two.TaskDispacther;
import com.example.nio.two.TaskThread;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;

/**
 * @Description
 * @Author 26233
 * @Create 2021-10-27 21:19:03
 */

/**
似乎可行

 一个ServerSocketChannel 注册到多个accept selector上，每个accept selector分配一个线程处理accept事件

 */
public class MultiSelectorServer4 {

    String hostName = "192.168.101.8";
    int port = 8888;
    int size = 4;

    Selector[] acceptSelectors = new Selector[size];

    Selector[] selectors = new Selector[size];
    AcceptSelectorThread[] acceptSelectorThreads = new AcceptSelectorThread[size];

    ReadSelectorThread2[] readSelectorThreads = new ReadSelectorThread2[size];

    TaskDispacther taskDispacther = new TaskDispacther();
    TaskThread[] taskThreads = new TaskThread[size];

    public void init(){

        ServerSocketChannel acceptSocketChannel = null;
        try {
            acceptSocketChannel = ServerSocketChannel.open();
            acceptSocketChannel.bind(new InetSocketAddress(hostName, port));
            acceptSocketChannel.configureBlocking(false);
        } catch (IOException e) {
            e.printStackTrace();
        }

        assert acceptSocketChannel != null;

        // 每个selector都会有事件通知到
        for (int i = 0; i < readSelectorThreads.length; i++) {
            try {
                acceptSelectors[i] = Selector.open();
                acceptSocketChannel.register(acceptSelectors[i], SelectionKey.OP_ACCEPT);
            } catch (IOException e) {
                e.printStackTrace();
            }
            acceptSelectorThreads[i] = new AcceptSelectorThread(acceptSelectors[i]);
            new Thread(acceptSelectorThreads[i]).start();

//            try {
//                selectors[i] = SelectorProvider.provider().openSelector();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//            readSelectorThreads[i] = new ReadSelectorThread2(selectors[i], taskDispacther);
//            taskThreads[i] = new TaskThread(taskDispacther);
//            new Thread(readSelectorThreads[i]).start();
//            new Thread(taskThreads[i]).start();

        }
    }

    public void start() throws IOException {

        init();

//        int selectorIndex = 0;
//        while (true){
//            acceptSelector.select();
//            Set<SelectionKey> selectionKeys = acceptSelector.selectedKeys();
//            Iterator<SelectionKey> iterator = selectionKeys.iterator();
//            while (iterator.hasNext()){
//                SelectionKey selectionKey = iterator.next();
//                iterator.remove();
//                try{
//                    if (selectionKey.isValid()){
//                        if (selectionKey.isAcceptable()){
//                            System.out.println("accept");
//                            ServerSocketChannel acceptChannel = (ServerSocketChannel) selectionKey.channel();
//                            SocketChannel client = acceptChannel.accept();
//                            client.configureBlocking(false);
//
//                            if (selectorIndex > 3){
//                                selectorIndex = 0;
//                            }
//                            selectors[selectorIndex].wakeup();
//                            client.register(selectors[selectorIndex++], SelectionKey.OP_READ);
//                        }else{
//                            System.out.println("key is not accept");
//                        }
//                    }
//                }catch (Exception e){
//                    e.printStackTrace();
//                    selectionKey.channel().close();
//                }
//            }
//        }
    }

    public static void main(String[] args) throws IOException {
        new MultiSelectorServer4().start();
    }
}